import { Cards, Card, Steps, Tabs } from 'nextra/components'
import BadgeGroup, { UniverTypes } from '@/components/BadgeGroup'

# 快速开始

<BadgeGroup values={[UniverTypes.SHEET, UniverTypes.DOC]} value={UniverTypes.SHEET} />

如果你想尽快开始体验 Univer，那么你来对地方了！这个页面将带你在几分钟内从零搭建一个可以运行的 Univer 应用。

## 在线体验

你可以在线体验 Univer，无需安装任何东西。只需点击下面的链接，即可立即开始使用 Univer。

<Cards>
  <Card
    icon="📊"
    title={<span className="">Univer Sheet</span>}
    href="https://stackblitz.com/~/github.com/awesome-univer/sheets-vite-demo"
  />
</Cards>

## 从模板创建

如果你想在本地搭建 Univer 应用，可以使用以下命令从模板创建一个新的 Univer 应用。

<Tabs items={['pnpm', 'npm']}>
  <Tabs.Tab label="pnpm">
    ```shell
    pnpm dlx degit dream-num/univer-sheet-start-kit [your-app-name]
    ```
  </Tabs.Tab>
  <Tabs.Tab label="npm">
    ```shell
    npx degit dream-num/univer-sheet-start-kit [your-app-name]
    ```
  </Tabs.Tab>
</Tabs>

至此，你已经成功创建了属于你的第一个 Univer 项目，并且体验了 Univer 的一些功能。

## 集成服务端的模板

当然，你有可能不满足于此，想要打印、导入导出、协同编辑等更多功能，这些功能需要更多的配置以及服务端的支持。不过不用担心，Univer 也为你提供了快速体验这些功能的方式，不妨照着下面的步骤来试试：

<Steps>
  ### 安装并运行服务端

  ```shell
  sh -c "$(curl -fsSL https://release-univer.oss-cn-shenzhen.aliyuncs.com/release-demo/install.sh)"
  ```

  ### 安装并运行前端

  <Tabs items={['pnpm', 'npm', '不使用包管理工具']}>
    <Tabs.Tab label="pnpm">
      ```shell
      pnpm dlx degit dream-num/univer-pro-sheet-start-kit [your-app-name]
      cd [your-app-name] && pnpm install # 注意：pnpm 版本需要 >= 8
      pnpm dev
      ```

      🎉 恭喜你，你又成功创建了一个包含了服务端的 Univer 项目，你可以访问 [http://localhost:5173/](http://localhost:5173/) 体验这些进阶的功能。

      你也可以在 [dream-num/univer-pro-sheet-start-kit](https://github.com/dream-num/univer-pro-sheet-start-kit) 找到该模板的源代码。
    </Tabs.Tab>
    <Tabs.Tab label="npm">
      ```shell
      npx degit dream-num/univer-pro-sheet-start-kit [your-app-name]
      cd [your-app-name] && npm install # 注意：npm 版本需要 >= 7
      npm run dev
      ```
            
      🎉 恭喜你，你又成功创建了一个包含了服务端的 Univer 项目，你可以访问 [http://localhost:5173/](http://localhost:5173/) 体验这些进阶的功能。

      你也可以在 [dream-num/univer-pro-sheet-start-kit](https://github.com/dream-num/univer-pro-sheet-start-kit) 找到该模板的源代码。
    </Tabs.Tab>
    <Tabs.Tab label="不使用包管理工具">
      如果你想不借助任何前端构建工具直接在浏览器中运行 Univer，你可以将以下代码复制保存到一个 HTML 文件中，然后双击在浏览器中打开该文件，即可体验打印、协同编辑、导入导出等功能。

      ```html
      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>
          Univer UMD With Collaboration, Live Share, Print, Exchange
        </title>
        <script src="https://unpkg.com/@univerjs/umd/lib/univer.full.umd.js"></script>
        <script src="https://unpkg.com/@univerjs/umd/lib/locale/zh-CN.js"></script>
        <link rel="stylesheet" href="https://unpkg.com/@univerjs/umd/lib/univer.css">

        <script src="https://unpkg.com/lodash/lodash.js"></script>
        <script> window.lodash = _ </script>

        <script src="https://unpkg.com/@univerjs-pro/collaboration/lib/umd/index.js"></script>
        <script src="https://unpkg.com/@univerjs-pro/collaboration-client/lib/umd/index.js"></script>
        <link rel="stylesheet" href="https://unpkg.com/@univerjs-pro/collaboration-client/lib/index.css">

        <script src="https://unpkg.com/@univerjs-pro/live-share/lib/umd/index.js"></script>
        <link rel="stylesheet" href="https://unpkg.com/@univerjs-pro/live-share/lib/index.css">

        <script src="https://unpkg.com/@univerjs-pro/print/lib/umd/index.js"></script>
        <script src="https://unpkg.com/@univerjs-pro/sheets-print/lib/umd/index.js"></script>
        <link rel="stylesheet" href="https://unpkg.com/@univerjs-pro/sheets-print/lib/index.css">

        <script src="https://unpkg.com/@univerjs-pro/sheets-exchange-client/lib/umd/index.js"></script>
        <link rel="stylesheet" href="https://unpkg.com/@univerjs-pro/sheets-exchange-client/lib/index.css">
        <style>
          body {
            margin: 0;
            padding: 0;
            font-family: Arial, sans-serif;
          }

          #app {
            height: 100vh;
            width: 100vw;
          }
        </style>
      </head>

      <body>
        <div id="app"></div>

        <script>
          // Hi, developer, this is a simple example to show how to use Univer UMD with collaboration, live share, print, exchange
          // If you want to use the collaboration, live share, print, exchange, you need to config the endpoint
          // The endpoint is the univer backend server that provides the collaboration, live share, print, exchange service
          // You can deploy the universer server on your own server, see the deployment guide: https://univer.ai/zh-CN/pro/guides/sheet/deployment/docker

          const universerEndpoint = 'localhost:8000';

          // check if the unit is already created
          const url = new URL(window.location.href)
          const unit = url.searchParams.get('unit')
          if (unit) {
            Promise.all([
              fetch('https://unpkg.com/@univerjs-pro/collaboration-client/lib/locale/en-US.json').then(res => res.json()),
              fetch('https://unpkg.com/@univerjs-pro/sheets-print/lib/locale/en-US.json').then(res => res.json()),
              fetch('https://unpkg.com/@univerjs-pro/sheets-exchange-client/lib/locale/en-US.json').then(res => res.json())
            ]).then(([
              collaborationLocale,
              printLocale,
              exchangeLocale
            ]) => {
              setup({
                ...collaborationLocale,
                ...printLocale,
                ...exchangeLocale
              });
            })
          } else {
            const { UniverInstanceType } = window.UniverCore;
            fetch(`http://${universerEndpoint}/universer-api/snapshot/${UniverInstanceType.UNIVER_SHEET}/unit/-/create`, {
              method: 'POST',
              headers: {
                'Content-Type': 'application/json',
              },
              body: JSON.stringify({
                type: UniverInstanceType.UNIVER_SHEET,
                name: 'New Sheet By Univer',
                creator: 'user',
              }),
            }).then((response) => {
              if (!response.ok) {
                throw new Error('Failed to create new sheet')
              }

              return response.json()
            }).then((data) => {
              if (!data.unitID) {
                throw new Error('create unit failed')
              }

              url.searchParams.set('unit', data.unitID)
              url.searchParams.set('type', String(UniverInstanceType.UNIVER_SHEET))
              window.location.href = url.toString()
            }).catch((error) => {
              console.error(error)
            })
          }

          const setup = (extLocale) => {
            var {
              UniverCore,
              UniverDesign,
              UniverEngineRender,
              UniverEngineFormula,
              UniverDocs,
              UniverDocsUi,
              UniverUi,
              UniverSheets,
              UniverSheetsUi,
              UniverSheetsNumfmt,
              UniverCollaboration,
              UniverCollaborationClient,
              UniverSheetsThreadComment
            } = window

            var univer = new UniverCore.Univer({
              theme: UniverDesign.defaultTheme,
              locale: UniverCore.LocaleType.ZH_CN,
              locales: {
                [UniverCore.LocaleType.ZH_CN]: {
                  ...UniverUMD['zh-CN'],
                  ...extLocale
                },
              },
              override: [
                [UniverCore.IAuthzIoService, null],
                [UniverCore.IUndoRedoService, null]
              ]
            });

            univer.registerPlugin(UniverEngineRender.UniverRenderEnginePlugin);
            univer.registerPlugin(UniverEngineFormula.UniverFormulaEnginePlugin);

            univer.registerPlugin(UniverUi.UniverUIPlugin, {
              container: "app",
            });

            univer.registerPlugin(UniverDocs.UniverDocsPlugin, {
              hasScroll: false,
            });
            univer.registerPlugin(UniverDocsUi.UniverDocsUIPlugin);

            univer.registerPlugin(UniverSheets.UniverSheetsPlugin);
            univer.registerPlugin(UniverSheetsUi.UniverSheetsUIPlugin);

            const { IThreadCommentMentionDataService, UniverSheetsThreadCommentPlugin } = UniverSheetsThreadComment;
            const mockUser = {
              userID: 'mockId',
              name: 'MockUser',
              avatar: '',
              anonymous: false,
              canBindAnonymous: false,
            };
            class CustomMentionDataService {
              trigger = '@';

              async getMentions (search) {
                return [
                  {
                    id: mockUser.userID,
                    label: mockUser.name,
                    type: 'user',
                    icon: mockUser.avatar,
                  },
                  {
                    id: '2',
                    label: 'User2',
                    type: 'user',
                    icon: mockUser.avatar,
                  },
                ];
              }
            }

            univer.registerPlugin(UniverSheetsThreadCommentPlugin, {
              overrides: [[IThreadCommentMentionDataService, { useClass: CustomMentionDataService }]],
            });

            //   pro
            const injector = univer.__getInjector();
            const configService = injector.get(UniverCore.IConfigService);

            // debug via reverse proxy
            const { SNAPSHOT_SERVER_URL_KEY, COLLAB_SUBMIT_CHANGESET_URL_KEY, COLLAB_WEB_SOCKET_URL_KEY, AUTHZ_URL_KEY } = UniverCollaborationClient;

            // config collaboration endpoint
            configService.setConfig(AUTHZ_URL_KEY, `http://${universerEndpoint}/universer-api/authz`);
            configService.setConfig(SNAPSHOT_SERVER_URL_KEY, `http://${universerEndpoint}/universer-api/snapshot`);
            configService.setConfig(COLLAB_SUBMIT_CHANGESET_URL_KEY, `http://${universerEndpoint}/universer-api/comb`);
            configService.setConfig(COLLAB_WEB_SOCKET_URL_KEY, `ws://${universerEndpoint}/universer-api/comb/connect`);

            // collaboration
            univer.registerPlugin(UniverCollaboration.UniverCollaborationPlugin);
            univer.registerPlugin(UniverCollaborationClient.UniverCollaborationClientPlugin);

            // live share
            univer.registerPlugin(UniverLiveShare.UniverLiveSharePlugin)

            // print
            univer.registerPlugin(UniverSheetsPrint.UniverSheetsPrintPlugin)

            // config import & export endpoint
            const { EXCHANGE_UPLOAD_FILE_SERVER_URL_KEY, EXCHANGE_IMPORT_SERVER_URL_KEY, EXCHANGE_EXPORT_SERVER_URL_KEY, EXCHANGE_GET_TASK_SERVER_URL_KEY, EXCHANGE_SIGN_URL_SERVER_URL_KEY } = UniverSheetsExchangeClient;
            configService.setConfig(EXCHANGE_UPLOAD_FILE_SERVER_URL_KEY, `http://${universerEndpoint}/universer-api/stream/file/upload`);
            configService.setConfig(EXCHANGE_IMPORT_SERVER_URL_KEY, `http://${universerEndpoint}/universer-api/exchange/{type}/import`);
            configService.setConfig(EXCHANGE_EXPORT_SERVER_URL_KEY, `http://${universerEndpoint}/universer-api/exchange/{type}/export`);
            configService.setConfig(EXCHANGE_GET_TASK_SERVER_URL_KEY, `http://${universerEndpoint}/universer-api/exchange/task/{taskID}`);
            configService.setConfig(EXCHANGE_SIGN_URL_SERVER_URL_KEY, `http://${universerEndpoint}/universer-api/file/{fileID}/sign-url`);

            // import & export
            univer.registerPlugin(UniverSheetsExchangeClient.UniverSheetsExchangeClientPlugin)
          }
        </script>
      </body>
      </html>
      ```
    </Tabs.Tab>
  </Tabs>
</Steps>

## 下一步

恭喜你！你已经迈出了第一步，开始了解 Univer。接下来，你可以继续深入学习 Univer，这里有一些建议：

- **🔰 安装和引入**：如果你想学习如何从头开始手动创建一个 Univer 项目，请查看[安装和引入](/guides/sheet/getting-started/installation)章节。它将一步步引导你完成整个过程。
- **🏗️ 进阶使用**：如果你想进一步提升你的 Univer 技能，可以查看[进阶使用](/guides/sheet/advanced/custom-canvas)章节。它涵盖了更多高级主题和技巧。
- **📚 教程**：如果你想了解一些实际的例子和真实的用例，可以查看[教程](/guides/sheet/tutorials/csv-import-plugin)章节，里面有一些实用的教程，可以帮助你学习如何使用 Univer 构建各种应用和功能。
- **🧱 概念与架构**：如果你想深入了解 Univer 的内部工作原理，可以查看 [架构](/guides/sheet/architecture/univer) 章节，它提供了 Univer 的架构、核心概念和设计原则的全面概述。
- **🎢 在线演示**： 别忘了探索[在线演示](/playground)页面，在那里你可以尝试各种 Univer 演示，看到这个库的实际运行。

无论你选择哪条道路，Univer 都会在你的每一步旅程中支持你。祝你开发愉快！
